package com.rs.admin.sys.oauth2;
import com.rs.admin.sys.org.entity.User;
import com.rs.admin.sys.org.entity.UserToken;
import com.rs.admin.sys.org.service.ShiroServcie;
import com.rs.common.utils.constant.Constant;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Set;

/**
 * 认证和授权的realm
 * @author hedonglin
 * @company 睿思科技
 * @email 1048791780@qq.com
 * @date 2017年12月13
 */
public class OAuth2Realm extends AuthorizingRealm{
    @Autowired
    private ShiroServcie shiroServcie;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof OAuth2Token;
    }

    /**
     * 根据token认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String accessToken = (String) token.getPrincipal();

        //根据accessToken，查询用户信息(id)
        UserToken tokenEntity = shiroServcie.findByToken(accessToken);

        //token失效处理
        if(tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()){
            throw new IncorrectCredentialsException("token失效，请重新登录");
        }
        //根据id查询用户信息
        User user = shiroServcie.findUserById(tokenEntity.getUserId());

        //判断账号是否锁定
        if (user.getStatus()== Constant.BaseStatus.FROZEN.getValue()){
            throw new LockedAccountException("账号已被锁定,请联系管理员");
        }
        //进行认证
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, accessToken, getName());
        return info;
    }

    /**
     * 根据凭证授权
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取认证后的用户信息
        User user = (User)principals.getPrimaryPrincipal();
        Long userId = user.getId();

        //通过用户信息查询用户权限
        Set<String> permsSet = shiroServcie.getUserPermissions(userId);

        //设置权限列表
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(permsSet);
        return info;
    }

}
